package com.plian.system.controller.fr.audit;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.DateUtil;
import com.plian.Tools.Func;
import com.plian.Tools.StringPool;
import com.plian.Tools.base.BaseController;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.annotation.LogOperation;
import com.plian.system.config.Resubmit;
import com.plian.system.dto.fr.audit.AuditReportDTO;
import com.plian.system.entity.fr.audit.AuditContact;
import com.plian.system.entity.fr.audit.AuditReport;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.search.TokenSearch;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.fr.audit.IAuditContactService;
import com.plian.system.service.fr.audit.IAuditReportService;
import com.plian.system.service.fr.audit.IAuditSystemService;
import com.plian.system.vo.fr.audit.AuditContactVO;
import com.plian.system.vo.fr.audit.AuditReportVO;
import com.plian.system.vo.report.ReportReturnVO;
import com.plian.system.wrapper.fr.audit.AuditContactWrapper;
import com.plian.system.wrapper.fr.audit.AuditReportWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;

/**
 * 内审报告备案管理 控制器
 *
 * @author gangan
 * @since 2019-09-30
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("api/auditreport")
public class AuditReportController extends BaseController {

    private IAuditReportService auditReportService;

    private IAuditContactService auditContactService;

    private IAuditSystemService auditSystemService;

    private AuditContactWrapper auditContactWrapper;

    private AuditReportWrapper auditReportWrapper;

    /**
     * 详情
     */
    @PostMapping("/detail")
    public ObjResult detail(@Valid @RequestBody AuditReport auditReport) {
        AuditReport detail = auditReportService.getOne(Condition.getQueryWrapper(auditReport));
        AuditReportVO auditReportVO =auditReportWrapper.entityToVO(detail);
        return auditReportService.getDetailObj(auditReportVO);

    }

    /**
     * 分页 内审报告备案管理
     */
    @PostMapping("/list")
    public ListResult<PageData> list(@Valid @RequestBody Query query) {
        List<SearchEntity> entityList = query.getSearch();

        if (query.getAscs()==null&&query.getDescs()==null){
            query.setDescs("create_time");
        }

        QueryWrapper<AuditReport> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new AuditReport()), entityList
        );
        TokenSearch<AuditReport> tokenSearch = new TokenSearch<>();
        if(null == query.getFlag()) query.setFlag(1);
		tokenSearch.addTokenQuery(queryWrapper, query);

        IPage<AuditReport> pages = auditReportService.page(Condition.getPage(query), queryWrapper);
        List<AuditReportVO> auditReportVOS = auditReportWrapper.entityToVO(pages.getRecords());
        List<PageData> pageDataList = new ArrayList<>();
        try {
            if (CollectionUtil.isNotEmpty(auditReportVOS)){
                for (AuditReportVO vo : auditReportVOS){
                    PageData pd = new PageData();
                    ObjectMapper mapper = new ObjectMapper();
                    String json = JSON.toJSONStringWithDateFormat(vo, DateUtil.PATTERN_DATETIME);
                    pd.putAll(mapper.readValue(json, new TypeReference<HashMap<String, String>>(){}));
                    pageDataList.add(pd);
                }
            }
            ListResult<PageData> listResult = new ListResult<>(CommonCode.SUCCESS);
            listResult.setList(pageDataList);
            listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
            return listResult;

        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }



    /**
     * 新增或修改 内审报告备案管理
     */
    @PostMapping("/submit")
    @Resubmit(delaySeconds = 0)
    @LogOperation("内审报告备案管理-提交")
    public ObjResult submit(@Valid @RequestBody AuditReport auditReport) {
        if (!(Optional.ofNullable(auditReport).isPresent() && Optional.ofNullable(auditReport.getStatus()).isPresent()
                && auditReport.getStatus() == -1)) {
            ObjResult result = auditReportService.checkSubmit(auditReport);
            if (Optional.ofNullable(result).isPresent()) {
                return result;
            }
        }
        return auditReportService.submit(auditReport) ? new ObjResult(CommonCode.SUCCESS) : new ObjResult(CommonCode.FAIL);
    }


    /**
     * 删除 内审报告备案管理
     */
    @PostMapping("/remove")
    @LogOperation("内审报告备案管理-删除")
    public ObjResult remove(@RequestBody PageData pd) {
        List<String> ids = (List<String>)pd.get("ids");
        return auditReportService.deleteLogic(Func.toLongList(StringUtils.join(ids, StringPool.COMMA)))? new ObjResult(CommonCode.SUCCESS) : new ObjResult(CommonCode.FAIL);
    }


    /**
     * 变更 内审报告备案管理
     */
    @PostMapping("/change")
    @LogOperation("内审报告备案管理-变更")
    public ObjResult change(@Valid @RequestBody AuditReport auditReport) {
        return auditReportService.change(auditReport);
    }

    /**
     * 企业内部审计工作情况统计表
     */
    @PostMapping("/auditStatistics")
    public ObjResult auditStatistics(@Valid @RequestBody(required = false) AuditReportDTO auditReportDTO) {
        ObjResult objResult;
        try {
            ReportReturnVO reportReturnVO = auditReportService.auditStatistics(auditReportDTO);
            objResult = new ObjResult(CommonCode.SUCCESS);
            if (Optional.ofNullable(reportReturnVO).isPresent()) {
                PageData pd = new PageData();
                pd.put("grids", reportReturnVO.getGrids());
                objResult.setPageData(pd);
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            objResult = new ObjResult(CommonCode.FAIL);
        }
        return objResult;
    }

    /**
     * 生成 企业内部审计工作情况统计表 excel文件
     * @param auditReportDTO
     * @return
     */
    @PostMapping("/export/auditStatistics")
    public ObjResult export(@Valid @RequestBody(required = false) AuditReportDTO auditReportDTO){
        PageData pd = new PageData();
        pd.put("key", auditReportService.exportAuditStatistics(auditReportDTO));
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pd);
        return objResult;
    }

    /**
     * 根据reportId获取内部审计负责人联系方式
     */
    @GetMapping("/getAuditContact")
    public ListResult<PageData> getAuditContact(Long reportId) {
        try {
            List<AuditContact> auditContacts = auditContactService.queryByReportId(reportId);
            List<PageData> pageDataList = new ArrayList<>();
            if (Optional.ofNullable(auditContacts).isPresent()) {
                List<AuditContactVO> auditContactVOS = auditContactWrapper.entityToVO(auditContacts);
                List<Map<String, Object>> maps = BeanUtils.beansToMaps(auditContactVOS);
                for(Map<String, Object> map : maps){
                    PageData pd = new PageData();
                    pd.putAll(map);
                    pageDataList.add(pd);
                }
            }
            ListResult<PageData> listResult = new ListResult<>(CommonCode.SUCCESS);
            listResult.setList(pageDataList);
            return listResult;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }

    /**
     * 内部审计负责人统计表
     * @param auditReportDTO
     * @return
     */
    @PostMapping("/auditContactStatistics")
    public ObjResult auditContactStatistics(@Valid @RequestBody(required = false) AuditReportDTO auditReportDTO) {
        ObjResult objResult;
        try {
            ReportReturnVO reportReturnVO = auditContactService.auditContactStatistics(auditReportDTO);
            objResult = new ObjResult(CommonCode.SUCCESS);
            if (Optional.ofNullable(reportReturnVO).isPresent()) {
                PageData pd = new PageData();
                pd.put("grids", reportReturnVO.getGrids());
                objResult.setPageData(pd);
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            objResult = new ObjResult(CommonCode.FAIL);
        }
        return objResult;
    }

    /**
     * 生成 内部审计负责人统计表 excel文件
     * @param auditReportDTO
     * @return
     */
    @PostMapping("/export/auditContactStatistics")
    public ObjResult exportAuditContactStatistics(@Valid @RequestBody(required = false) AuditReportDTO auditReportDTO){
        PageData pd = new PageData();
        pd.put("key", auditReportService.exportAuditContactStatistics(auditReportDTO));
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pd);
        return objResult;
    }

    /**
     * 内部审计相关制度统计
     * @param auditReportDTO
     * @return
     */
    @PostMapping("/auditSystemStatistics")
    public ObjResult auditSystemStatistics(@Valid @RequestBody(required = false) AuditReportDTO auditReportDTO) {
        ObjResult objResult;
        try {
            ReportReturnVO reportReturnVO = auditSystemService.auditSystemStatistics(auditReportDTO);
            objResult = new ObjResult(CommonCode.SUCCESS);
            if (Optional.ofNullable(reportReturnVO).isPresent()) {
                PageData pd = new PageData();
                pd.put("grids", reportReturnVO.getGrids());
                objResult.setPageData(pd);
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            objResult = new ObjResult(CommonCode.FAIL);
        }
        return objResult;
    }

    /**
     * 生成 内部审计相关制度统计 excel文件
     * @param auditReportDTO
     * @return
     */
    @PostMapping("/export/auditSystemStatistics")
    public ObjResult exportAuditSystemStatistics(@Valid @RequestBody(required = false) AuditReportDTO auditReportDTO){
        PageData pd = new PageData();
        pd.put("key", auditReportService.exportAuditSystemStatistics(auditReportDTO));
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pd);
        return objResult;
    }


    /**
     * 下载excel文件 并删除
     * @param key
     * @param response
     */
    @GetMapping("/download/{key}")
//    @PassToken
    public void download(@PathVariable String key, HttpServletResponse response){
        auditReportService.download(key, response);
    }

    /**
     * 生成excel文件
     * @param id
     * @return
     */
    @GetMapping("/export/{id}")
    public ObjResult export(@PathVariable Long id){
        PageData pd = new PageData();
        pd.put("key", auditReportService.export(id));
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pd);
        return objResult;
    }
}
